import type { AppointmentManagement } from '@shared/types/'
import type { BookingOptions, BookingOutcome, BookingStrategy } from './strategy'
import { BookingEngineForBooking } from './booking-engine-booking'
import { registerEngine, unregisterEngine } from './engine-registry'

/**
 * Playwright 模式策略：
 * - 组装 automation 引擎所需的上下文（user_info / preferredDates / preferredTimes / options）。
 * - 直接复用预约引擎执行，并将执行结果映射为 BookingOutcome。
 */
export class PlaywrightBookingStrategy implements BookingStrategy {
  async book(appointment: AppointmentManagement, options?: BookingOptions): Promise<BookingOutcome> {
    // 每次预约创建独立引擎实例，避免并发任务共享单例互相干扰
    const engine = new BookingEngineForBooking()
    registerEngine(engine)
    // 解析首选日期：优先 options.preferredDates，其次 appointment.preferred_dates
    const parsePreferredFromAppointment = (): string[] => {
      try {
        const raw: any = (appointment as any)?.preferred_dates
        if (!raw)
          return []
        if (Array.isArray(raw))
          return raw.filter(Boolean).map(String)
        const s = String(raw)
        // JSON 数组或逗号/分号/空格分隔
        if (s.trim().startsWith('[')) {
          try { const arr = JSON.parse(s); return Array.isArray(arr) ? arr.filter(Boolean).map(String) : [] }
          catch { /* fallthrough */ }
        }
        return s.split(/[;,\s]+/).map(t => t.trim()).filter(Boolean)
      }
      catch { return [] }
    }
    const preferredDates = Array.isArray(options?.preferredDates) && options!.preferredDates.length > 0
      ? options!.preferredDates
      : parsePreferredFromAppointment()

    const ctx = {
      user_info: {
        passport_number: appointment.passport_number,
        license_number: appointment.license_number,
        license_owner_name: appointment.full_name,
        email: appointment.email,
        phone_number: appointment.phone_number || '',
        issuing_country: appointment.issuing_country as any,
        issuing_authority: appointment.issuing_authority as any,
        service_type: appointment.service_type,
      },
      preferred_dates: preferredDates,
      preferred_times: options?.preferredTimes || [],
      options: {
        headless: options?.headless ?? true,
        timeout: options?.timeoutMs ?? 30000,
        save_html: true,
        // 将会话级允许日期范围传递给引擎，字段名与引擎读取一致
        allowed_date_range: options?.allowedDateRange,
        // 将预约记录上的 UA 传入引擎（BrowserManager 将优先使用 options.user_agent）
        user_agent: (appointment as any)?.user_agent,
      },
      // 传递原始预约数据以便引擎判断 force_preferred_dates
      appointment,
    } as any

    // 钩住引擎内部 updateProgress，向外部回调
    const originalUpdateProgress = (engine as any).updateProgress?.bind(engine)
    const patchedUpdate = async (progress: number, step: string) => {
      try {
        if (typeof options?.onProgress === 'function')
          options.onProgress({ progress, step, timestamp: Math.floor(Date.now() / 1000) })
      }
      catch {}
      // 将步骤同步给浏览器管理器用于分步流量统计
      try { (engine as any).getBrowserManager?.().setCurrentStepLabel?.(step) }
      catch {}
      try { return await originalUpdateProgress?.(progress, step) }
      catch { /* ignore */ }
    }
    // 尝试打补丁
    try { (engine as any).updateProgress = patchedUpdate }
    catch {}

    const result = await engine.execute(ctx)
    // 附加流量统计到 outcome（以便上层写库时可用）
    try {
      const bm = (engine as any).getBrowserManager?.()
      if (bm?.getTrafficSnapshot) {
        const t = bm.getTrafficSnapshot()
        ;(result as any).traffic = t
      }
    }
    catch {}
    finally {
      try { unregisterEngine(engine) }
      catch {}
    }
    if (result.success) {
      return {
        success: true,
        referenceNumber: (ctx as any).session_data?.reference_number,
        selectedDate: (ctx as any).selected_date,
        selectedTimeslot: (ctx as any).selected_timeslot?.display_time,
        traffic: (result as any)?.traffic,
      }
    }
    else {
      return { success: false, error: result.message || 'failed', traffic: (result as any)?.traffic }
    }
  }
}
